<?php
/**
 * CK框架 控制器类。
 * @category   CkFrameWork
 * @package  CkFrameWork
 * @subpackage lib
 * @author    wujibing<283109896@qq.com>
 * @version   3.0
 */
class action extends ckEventObejct
{
    /**
     * 添加数据的事件名称
     * @var string
     */
    const EVENT_ADD_DATA = 'EVENT_ADD_DATA';
    /**
     * 编辑数据的事件名称
     * @var string
     */
    const EVENT_UPDATE_DATA = 'EVENT_UPDATE_DATA';
    /**
     * 删除数据的事件名称
     * @var string
     */
    const EVENT_DELETE_DATA = 'EVENT_DELETE_DATA';
    /**
     * 删除和编辑数据的时候用到的校验数据回调方法
     * @var string
     */
    const EVENT_CHECK_DATA = 'EVENT_CHECK_DATA';
	/**
	 * 方法名字
	 * @var string
	 */
	protected $_methodName = '';
	/**
	 * 控制器名
	 * @var string
	 */
	protected $_actionName = '';
	/**
	 * 控制器对应的模块
	 * @var module
	 */
	protected $_module = null;
	/**
	 * 不允许调用的方法
	 * @var array
	 */
	protected $_notAllowFunctions = array('getActionName', 'getMethodName', 'setModule','checkMethodName','hasModule','actionInit');
	/**
	 * 视图类型
	 * @var string
	 */
	protected $viewType = 'html';
	/**
	 * 分页每页数量
	 * @var int
	 */
	protected $pageNum = 20;
	/**
	 * 验证表单的名称
	 * @var string
	 */
	protected $_verifyFormName = '';
	/**
	 * 当该值存在的时候 控制器就会加载该项模型
	 * @var string
	 */
	protected $_moduleName = '';
	/**
	 * 初始化类
	 * @param string $_actionName
	 * 控制器名
	 * @param string $_methodName
	 * 方法名
	 */
	public function __construct ()
	{
	}
	public function actionInit($_actionName, $_methodName)
	{
	    $this->_actionName = $_actionName;
	    $this->_methodName = $_methodName;
	    $this->_verifyFormName = $this->_actionName.$this->_methodName;
	    if(isset($_REQUEST['ajaxType']) && $_REQUEST['ajaxType'])
	    {
	        $this->viewType = $_REQUEST['ajaxType'];
	    }
	}
	/**
	 * 判断调用的方法是否允许调用
	 * @throws base_base_Exception
	 */
	public function checkMethodName ()
	{
		if (in_array($this->_methodName, $this->_notAllowFunctions))
		{
			ckApplication::set404(lang::getLang('__CANNOT_CALL_METHOD__',array($this->_methodName)));
		}
	}
	/**
	 * 获取控制器名
	 * @return string
	 */
	public function getActionName ()
	{
		return $this->_actionName;
	}
	/**
	 * 判断是否有模块
	 * @return boolean
	 */
	public function hasModule()
	{
		return $this->_module != null;
	}
	/**
	 * 获取控方法名字
	 * @return string
	 */
	public function getMethodName ()
	{
		return $this->_methodName;
	}

	/**
	 * 设置模块
	 * @param module $module
	 */
	public function loadModule ()
	{
	    if($this->_module !== null)
	    {
	        return ;   
	    }
	    $tmp = $this->_actionName.'_'.CK_APPLICATION_NAME;
	    if($this->_moduleName)
	    {
	        $this->_module = ckApplication::loadM($this->_moduleName);
	    } else if(!file::exists(CK_APPLICATION_DIR.'lib/module/'.$tmp.'_module.class.php'))
	    {
	        $this->_module = new module($this->_actionName);
	    } else
	    {
	        $this->_module = ckApplication::loadM($tmp);
	    }
	    //添加默认的事件
	    $this->attach(self::EVENT_ADD_DATA, array($this->_module,'add'));
	    $this->attach(self::EVENT_UPDATE_DATA, array($this->_module,'update'));
	    $this->attach(self::EVENT_DELETE_DATA, array($this->_module,'delete'));
	    $this->attach(self::EVENT_CHECK_DATA, array($this,'checkDataPrimary'));
	}
	/**
	 * 默认的主页
	 */
	public function main()
	{
		$count = $this->_module->count();
		try
		{
			$this->assgin('pageData',page::getPage((int) $_GET['page'], $count, $this->pageNum));
		} catch (nowPageLtMaxPage_page_Exception $e)
		{
			ckApplication::showMessage($e->getMessage());
		}
		$nowPage = page::getNowPage();
		$maxPage = page::getMaxPage();
		$this->assgin('nowPage', $nowPage);
		$this->assgin('maxPage', $maxPage);
		$this->assgin('count', $count);
		if ($maxPage)
		{
			$pageNum = page::getPageNum();
			//解析url地址
			$appendUrl = '?';
			unset($_GET['page']);
			foreach ($_GET as $k => $v)
			{
				$appendUrl .= '&' . $k . '=' . $v;
			}
			$this->assgin('pageUrl', $appendUrl);
			$nowPage = $nowPage - 1;
			$nowPage < 0 ? $nowPage = 0 : '';
			$data = $this->_module->limit($nowPage * $pageNum, $pageNum)->query();
			$this->assgin('data', $data);
		}
		$this->display();
	}
	/**
	 * 提供给子类编辑的一个方法
	 * 如果采用默认的方法 则子类不用添加edit方法
	 * @throws base_base_Exception
	 */
	public function edit()
	{
		$this->run(self::EVENT_CHECK_DATA);
		if (isset($_POST['dosubmit']) && form::checkVerifyKey($this->_verifyFormName))
		{
			try
			{
			    //建立更新数据的通知
			    $this->run(self::EVENT_UPDATE_DATA,array($_POST['poster']));
			} catch (queryFaild_sql_Exception $e)
			{
				//如果是查询异常。那么则交由base异常类进行调出，显示详细信息
				throw new base_Exception($e);
			} catch (Exception $e)
			{
				ckApplication::showMessage($e->getMessage());
			}
			ckApplication::showMessage(lang::getLang('__OPERATION_WAS_SUCCESSFUL__'));
		}
		$this->assgin('value', $this->_module->getData());
		$this->display();
	}
	public function del()
	{
		$this->run(self::EVENT_CHECK_DATA);
		$message = lang::getLang('__OPERATION_WAS_SUCCESSFUL__');
		try 
		{
		    //通知删除事件
		    $this->run(self::EVENT_DELETE_DATA);
		} catch (Exception $e)
		{
			$message = $e->getMessage();
		}
		ckApplication::showMessage($message,ckApplication::createUrl($this->_actionName));
	}
	/**
	 * 用于校验编辑和删除的数据是否存在
	 */
	protected function checkDataPrimary()
	{
	    $id = (int) $_GET[$this->_module->getPrimary()];
	    if (!$id || ! $this->_module->find($id))
	    {
	        ckApplication::showMessage(lang::getLang('__PARAMETER_ERROR__'));
	    }
	}
	public function add()
	{
		if (isset($_POST['dosubmit']) && form::checkVerifyKey($this->_verifyFormName))
		{
			try
			{
			    //通知添加事件
			    $this->run(self::EVENT_ADD_DATA,array($_POST['poster']));
			} catch (queryFaild_sql_Exception $e)
			{
				//如果是查询异常。那么则交由base异常类进行调出，显示详细信息
				throw new base_Exception($e);
			} catch (Exception $e)
			{
				//$this->addFasleCallBack($e->getMessage());
				ckApplication::showMessage($e->getMessage());
			}
			//$this->addTrueCallBack();
			ckApplication::showMessage(lang::getLang('__OPERATION_WAS_SUCCESSFUL__'));
		}
		$this->display();
	}
	/**
	 * 输出数据
	 * 参数用于缓存页面数据
	 * 两项默认$fileName优先级更高
	 * 当$fileName存在的时候 则生成页面数据到 $fileName
	 * 当$time存在的时候 则生成缓存数据。直接在控制器$this->checkCachePage();输出页面
	 * @param string $fileName 保存的文件名
	 * @param int $time 保存时间
	 */
	protected function display($fileName = '',$time = -1)
	{
		switch ($this->viewType)
		{
			case 'json':
				view::displayJson();
				break;
			case 'xml':
				view::displayXml();
				break;
			default:
				view::display($this->_actionName, $this->_methodName);
		}
		view::endFlush($fileName,$time);
	}
	/**
	 * 判断是否有页面缓存
	 * 有缓存的话直接输出缓存 并且终止程序运行
	 */
	protected function checkCachePage()
	{
	    cache::init(cacheType::FILE);
	    $pageContent = cache::get(pageCache::getPageId());
	    if($pageContent)
	    {
	        echo $pageContent;
	        exit;    
	    }
	}
	
	/**
	 * 为视图添加和更新数据
	 * @param string $name
	 * @param mixed $data
	 */
	protected function assgin($name,$data)
	{
		view::addData($name, $data);
	}
	/**
	 * 为视图合并数据
	 * @param array $data
	 */
	protected function mergeData($data)
	{
		view::mergeData($data);
	}
	/**
	 * 增加不允许调用的方法
	 * 提供子类使用
	 * @param string $functionName
	 */
	protected function addNotAllowFunction($functionName)
	{
		$this->_notAllowFunctions[] = $functionName;
	}
}